package com.ai.imagetext.service;

import com.ai.imagetext.dto.TagDTO;
import com.ai.imagetext.entity.Tag;
import com.ai.imagetext.repository.TagRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class TagService {
    
    private final TagRepository tagRepository;
    
    /**
     * 获取所有标签
     */
    public List<TagDTO> getAllTags() {
        log.info("Getting all tags");
        
        List<Tag> tags = tagRepository.findByIsDeletedFalseOrderByUsageCountDesc();
        return tags.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    /**
     * 根据分类获取标签
     */
    public List<TagDTO> getTagsByCategory(String category) {
        log.info("Getting tags by category: {}", category);
        
        List<Tag> tags = tagRepository.findByCategoryAndIsDeletedFalse(category);
        return tags.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    /**
     * 搜索标签
     */
    public List<TagDTO> searchTags(String keyword) {
        log.info("Searching tags with keyword: {}", keyword);
        
        List<Tag> tags = tagRepository.findByNameContainingAndIsDeletedFalse(keyword);
        return tags.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    /**
     * 获取热门标签
     */
    public Page<TagDTO> getPopularTags(int page, int size) {
        log.info("Getting popular tags: page={}, size={}", page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Tag> tagPage = tagRepository.findByIsDeletedFalseOrderByUsageCountDesc(pageable);
        return tagPage.map(this::convertToDTO);
    }
    
    /**
     * 获取最新标签
     */
    public Page<TagDTO> getLatestTags(int page, int size) {
        log.info("Getting latest tags: page={}, size={}", page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Tag> tagPage = tagRepository.findByIsDeletedFalseOrderByCreatedAtDesc(pageable);
        return tagPage.map(this::convertToDTO);
    }
    
    /**
     * 根据ID获取标签
     */
    public Optional<TagDTO> getTagById(Long id) {
        log.info("Getting tag by ID: {}", id);
        
        Optional<Tag> tag = tagRepository.findById(id);
        return tag.filter(t -> !t.getIsDeleted()).map(this::convertToDTO);
    }
    
    /**
     * 根据名称获取标签
     */
    public Optional<TagDTO> getTagByName(String name) {
        log.info("Getting tag by name: {}", name);
        
        Optional<Tag> tag = tagRepository.findByNameAndIsDeletedFalse(name);
        return tag.map(this::convertToDTO);
    }
    
    /**
     * 创建标签
     */
    @Transactional
    public TagDTO createTag(TagDTO tagDTO) {
        log.info("Creating tag: {}", tagDTO.getName());
        
        // 检查标签是否已存在
        Optional<Tag> existingTag = tagRepository.findByNameAndIsDeletedFalse(tagDTO.getName());
        if (existingTag.isPresent()) {
            throw new IllegalArgumentException("标签已存在：" + tagDTO.getName());
        }
        
        Tag tag = new Tag();
        tag.setName(tagDTO.getName());
        tag.setCategory(tagDTO.getCategory() != null ? tagDTO.getCategory() : "manual");
        tag.setUsageCount(0);
        tag.setIsDeleted(false);
        
        Tag savedTag = tagRepository.save(tag);
        return convertToDTO(savedTag);
    }
    
    /**
     * 更新标签
     */
    @Transactional
    public TagDTO updateTag(Long id, TagDTO tagDTO) {
        log.info("Updating tag: {}", id);
        
        Tag tag = tagRepository.findById(id)
                .filter(t -> !t.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("标签不存在或已删除"));
        
        if (tagDTO.getName() != null && !tagDTO.getName().equals(tag.getName())) {
            // 检查新名称是否已存在
            Optional<Tag> existingTag = tagRepository.findByNameAndIsDeletedFalse(tagDTO.getName());
            if (existingTag.isPresent() && !existingTag.get().getId().equals(id)) {
                throw new IllegalArgumentException("标签名称已存在：" + tagDTO.getName());
            }
            tag.setName(tagDTO.getName());
        }
        
        if (tagDTO.getCategory() != null) {
            tag.setCategory(tagDTO.getCategory());
        }
        
        Tag savedTag = tagRepository.save(tag);
        return convertToDTO(savedTag);
    }
    
    /**
     * 删除标签
     */
    @Transactional
    public void deleteTag(Long id) {
        log.info("Deleting tag: {}", id);
        
        Tag tag = tagRepository.findById(id)
                .filter(t -> !t.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("标签不存在或已删除"));
        
        tagRepository.softDeleteById(id);
    }
    
    /**
     * 获取标签统计信息
     */
    public TagStatistics getTagStatistics() {
        log.info("Getting tag statistics");
        
        long totalTags = tagRepository.countByIsDeletedFalse();
        List<Object[]> categoryStats = tagRepository.getCategoryStatistics();
        
        TagStatistics stats = new TagStatistics();
        stats.setTotalTags(totalTags);
        stats.setCategoryStats(categoryStats.stream()
                .collect(Collectors.toMap(
                        result -> (String) result[0],
                        result -> ((Number) result[1]).longValue()
                )));
        
        return stats;
    }
    
    /**
     * 转换为DTO
     */
    private TagDTO convertToDTO(Tag tag) {
        TagDTO dto = new TagDTO();
        dto.setId(tag.getId());
        dto.setName(tag.getName());
        dto.setCategory(tag.getCategory());
        dto.setUsageCount(tag.getUsageCount());
        dto.setCreatedAt(tag.getCreatedAt());
        dto.setUpdatedAt(tag.getUpdatedAt());
        return dto;
    }
    
    /**
     * 标签统计信息
     */
    public static class TagStatistics {
        private long totalTags;
        private java.util.Map<String, Long> categoryStats;
        
        // Getters and Setters
        public long getTotalTags() { return totalTags; }
        public void setTotalTags(long totalTags) { this.totalTags = totalTags; }
        
        public java.util.Map<String, Long> getCategoryStats() { return categoryStats; }
        public void setCategoryStats(java.util.Map<String, Long> categoryStats) { this.categoryStats = categoryStats; }
    }
}